import config
import obj_config
from fuzzywuzzy import fuzz


class Tags_decoder:
    def dec_recognition_marks(
        self, cmd_str_tags: str, name_func: str = "", tags_all_list: list = []
    ) -> dict:
        if len(tags_all_list) == 0 and len(name_func) == 0:
            if config.cmds["metka"]:
                tags_all_list = config.cmds["metka"]
            else:
                return {}
        elif name_func:
            if ("tags_list" in config.cmds["void"][name_func]["tags"]["tags"]):
                if (
                    len(config.cmds["void"][name_func]["tags"]["tags"]["tags_list"])
                    != 0
                ):
                    tags_all_list = config.cmds["void"][name_func]["tags"]["tags"][
                        "tags_list"
                    ]
                else:
                    return {}
            else:
                return {}
        cmd_str_tags = obj_config.service_functions_obj.error_correction(
            cmd_str_tags, tags_all_list, name_err=2
        )
        cmd_list_tags = cmd_str_tags.split(" ")
        tags_key = []
        tags_values = []
        index_old = -1
        for index, value in enumerate(cmd_list_tags):
            if value in tags_all_list:
                if index_old != -1:
                    tags_key.append(cmd_list_tags[index])
                    tags_values.append(" ".join(cmd_list_tags[index_old + 1 : index]))
                else:
                    tags_key.append(cmd_list_tags[index])
                if index == index_old + 1 and index_old != -1:
                    return {}
                index_old = index
            elif index == len(cmd_list_tags) - 1:
                tags_values.append(
                    " ".join(cmd_list_tags[index_old + 1 : len(cmd_list_tags)])
                )
        return {"tags": tags_key, "value": tags_values}

    """
    def dec_recognition_marks(self,cmd_str_tags:str,name_func:str="",tags_all_list:list=[])  ->  dict:
        if len(tags_all_list) == 0 and len(name_func) == 0:
            print(333333)
            if len(config.cmds['metka']) != 0:
                tags_all_list = config.cmds['metka']
            else:
                return {}
        elif len(name_func) != 0:
            print(name_func,22222)
            if ("tags_list" in config.cmds_void[name_func]) == True:
                if len(config.cmds_void[name_func]["tags_list"]) != 0:
                    tags_all_list = config.cmds_void[name_func]["tags_list"]
                else:
                    return {}
            else:
                return {}
        cmd_str_tags = obj_config.service_functions_obj.error_correction(cmd_str_tags, tags_all_list, name_err=2)
        cmd_list_tags = cmd_str_tags.split(' ')
        index_list_tags = []
        name_list_tags = []
        str_tags_rezalt = []
        for index, tags in enumerate(cmd_list_tags):
            if (tags in tags_all_list) == True:
                index_list_tags.append(index)
                name_list_tags.append(tags)
            else:
                pass

        len_index_tags = len(index_list_tags)
        index_1 = 0
        while len_index_tags - 1 > index_1:
            list_tags_info = cmd_list_tags[index_list_tags[index_1] + 1:index_list_tags[index_1 + 1]]
            str_tags_info = ' '.join(list_tags_info)
            str_tags_rezalt.append(str_tags_info)
            index_1 += 1
        if (("" in name_list_tags)  or ("" in str_tags_rezalt))==True or ((" " in name_list_tags)  or ("" in str_tags_rezalt))==True:
            return {}
        else:
            d = {"tags": name_list_tags, "value": str_tags_rezalt}
            return d
    """

    def translate_tags(self, tags: list) -> list:
        return obj_config.obj_number_dec.number_activation_label(tags)


class Tags_wraper(Tags_decoder):
    def dec_activation_tags(self, str_tags, func: str = "") -> list:
        tags = self.dec_recognition_marks(str_tags, func)
        # print(tags)
        if len(tags) != 0:
            tags = tags["value"]
            tags = obj_config.obj_number_dec.number_activation_label(tags)
            return tags
        else:
            return []

    """
    def check_tags(self, func, tags):
        if len(func) != 0:
            tags_type = config.cmds[func]['void_info']['metka_type']
            tags_kol = config.cmds[func]['void_info']['metka_kol']
            if (len(tags_type) != len(tags)) and (len(tags_type) != tags_kol):
                return False
            elif (len(tags_type) == len(tags)) and (len(tags_type) == tags_kol):
                for x in range(len(tags_type)):
                    if type(tags_type[x]) == type(tags[x]):
                        pass
                    elif type(tags_type[x]) != type(tags[x]):
                        return False
                return True
            else:
                return False
        else:
            return False
    """

    def check_tags(self, func, tags):
        tags_kol = config.cmds["void"][func]["tags"]["tags"]["label_count"]
        if len(tags) != 0:
            return tags_kol == len(tags)
        else:
            return False

    def loop_tags(self) -> dict:
        cmd_tags_value_all = []
        cmd_tags_mark_all = []
        menu_flag = ""
        obj_config.communication_obj.messege("Циклическая обработка меток")
        while "end" not in menu_flag:
            str_cmd = config.stream_speech.get()
            cmd = obj_config.wrapper_decoders_obj.dec_function_recognition(
                str_cmd, "loop_make"
            )
            if cmd in config.cmds["loop_make"]:
                menu_flag = cmd
            if ("pause" not in menu_flag) and ("return_tags" not in menu_flag):
                cmd_tags = self.dec_recognition_marks(str_cmd)
                cmd_tags_value_all = cmd_tags_value_all + cmd_tags["value"]
                cmd_tags_mark_all = cmd_tags_mark_all + cmd_tags["value"]
            elif ("return_tags" in menu_flag):
                obj_config.communication_obj.messege(" ".join(cmd_tags_value_all))
            elif ("clear" in menu_flag):
                cmd_tags_value_all.clear()
                cmd_tags_mark_all.clear()
                obj_config.communication_obj.messege("Метка очишена")
            else:
                pass
        return {"value": cmd_tags_value_all, "tags": cmd_tags_mark_all}

    def tags_params(self, cmd):
        # ["tags","value","tags","value","tags","value","tags"]
        tags = self.dec_recognition_marks(cmd)
        tags_value = tags["value"]
        tags_mark = tags["tags"]
        tags_all = []
        for x in range(len(tags_mark)):
            tags_all.append(tags_mark[x])
            tags_all.append(tags_value[x])
        return tags_all

    def selection_tags(self, str_tags: str = "", func: str = "") -> list:
        # Если настройка в config.tags_decoder_flag==True
        # Обработка меток в цикле
        if config.tags_decoder_flag:
            return self.loop_tags()["value"]
        else:
            if len(str_tags) != 0:
                return self.dec_activation_tags(str_tags)
            else:
                return self.dec_activation_tags(
                    self.mess_tags(obj_config.obj_api.queue_voice_time_str_api), func
                )

    def mess_tags(self, str_cmd):
        obj_config.communication_obj.message("Скажите метки")
        return str_cmd()


class Tags_v2:
    def cheek_value_tags_v2(self, func, tags):
        # Баги исправить !!! б
        dict_value = config.cmds_void[func]["label_dict_word_value_in_values"]
        flag = False
        for value in tags:
            if value in dict_value or value == "all":
                flag = True
            else:
                # flag = False
                pass
        return True

    """

    def cheek_tags_v2(self, func, str_tags):
        try:
            if config.cmds_void[func]["label_dict_word_bool"]:
                if str_tags != "":
                    return self.func_tags_decoder_v2(str_tags, func)
                else:
                    return "error"
            else:
                return ""
        except BaseException:
            return ""
    """

    def __func_s_r_recog(self, cmd_str, key, func):
        list_tags = []
        if (config.cmds_void[func]["type_label_dict_word"] == "global"):
            if (key in config.cmds["dict_words"]):
                for key_index, values in enumerate(
                    config.cmds["dict_words"][key]["lang"]
                ):
                    for value in values:
                        Levenshtein_d = fuzz.partial_ratio(cmd_str, value)
                        # print(Levenshtein_d)
                        obj_config.service_functions_obj.fuzz_word_cheek(value)
                        if Levenshtein_d >= config.probability_cmd:
                            tags_cmd = config.cmds["dict_words"][key]["cmd"][key_index]
                            list_tags.append(tags_cmd)
        elif (config.cmds_void[func]["type_label_dict_word"] == "local"):
            if (key in config.cmds_void[func]["dict_words"]):
                for key_index, values in enumerate(
                    config.cmds_void[func]["dict_words"][key]["lang"]
                ):
                    for value in values:
                        Levenshtein_d = fuzz.partial_ratio(cmd_str, value)
                        # print(Levenshtein_d)
                        # Заменить на try ?
                        obj_config.service_functions_obj.fuzz_word_cheek(value)
                        if Levenshtein_d >= config.probability_cmd:
                            tags_cmd = config.cmds_void[func]["dict_words"][key]["cmd"][
                                key_index
                            ]
                            list_tags.append(tags_cmd)

        return list_tags

    def __func_convert_list_dict_value(self, tags_values, key, func):
        tags_set = {}
        if (config.cmds_void[func]["type_label_dict_word"] == "global"):
            if (key in config.cmds["dict_word_cmd_value"]):
                for value in tags_values:
                    # Заменить на try ?
                    if value in config.cmds["dict_word_cmd_value"][key]:
                        tags_cmd = config.cmds["dict_word_cmd_value"][key][value]
                        tags_set[value] = tags_cmd
        elif (config.cmds_void[func]["type_label_dict_word"] == "local"):
            if (key in config.cmds_void[func]["dict_word_cmd_value"]):
                for value in tags_values:
                    # Заменить на try ?
                    if value in config.cmds_void[func]["dict_word_cmd_value"][key]:
                        tags_cmd = config.cmds_void[func]["dict_word_cmd_value"][key][
                            value
                        ]
                        tags_set[value] = tags_cmd
        return tags_set

    def func_tags_decoder_v2(self, cmd_str, func):
        """Поиск ключевых слов из списка"""
        dict_values = {}
        if config.cmds_void[func]["label_dict_word_bool"]:
            keys = config.cmds_void[func]["label_dict_word_values"]
            dict_values = {}
            for key in keys:
                list_key_value = self.__func_s_r_recog(cmd_str, key, func)
                values = self.__func_convert_list_dict_value(list_key_value, key, func)
                if len(values) != 0:
                    dict_values.update(values)
            return dict_values
        else:
            return dict_values

    def cheek_tags_v2(self, func, cmd_say):
        if "tags" in config.cmds_void[func]["tags"]:
            return "tags"
        elif "key" in config.cmds_void[func]["tags"]:
            return "key"
        else:
            return "error"

    def dec_function_recognition_keys(self, cmd_str, func, tags, dict_words) -> dict:
        len_str_cmd = len(cmd_str)
        list_value = []
        list_key = []
        list_key_value = []
        if len_str_cmd != 0:
            par = 100 / len_str_cmd
            booleen = int(par + config.probability_cmd_const) <= 100
            if booleen:
                if len_str_cmd != 0:
                    for dict_names in dict_words:
                        for key in tags[dict_names]:
                            for value_str in tags[dict_names][key]:
                                obj_config.service_functions_obj.fuzz_word_cheek(
                                    len(value_str)
                                )
                                Levenshtein_d = fuzz.partial_ratio(cmd_str, value_str)
                                if Levenshtein_d >= config.probability_cmd:
                                    if len(value_str) == 0:
                                        return {
                                            "key": list_key,
                                            "values": list_value,
                                            "key_value": list_key_value
                                        }
                                    elif len(value_str) > 0:
                                        list_value.append(value_str)
                                        list_key.append(key)
                                        list_key_value.append(
                                            {key: dict_words[dict_names][key]}
                                        )

            else:

                for dict_names in dict_words:
                    for key in tags[dict_names]:

                        for value_str in tags[dict_names][key]:
                            obj_config.service_functions_obj.fuzz_word_cheek(
                                len(value_str)
                            )
                            Levenshtein_d = fuzz.partial_ratio(cmd_str, value_str)
                            if Levenshtein_d >= config.probability_cmd:
                                list_value.append(value_str)
                                list_key.append(key)
                                list_key_value.append(
                                    {key: dict_words[dict_names][key]}
                                )
                            else:
                                pass
        return {"key": list_key, "values": list_value, "key_value": list_key_value}

    def dict_word_searhc(self, cmd_str, func):
        where_to_look = config.cmds["void"][func]["tags"]["key"]["where_to_look"]
        if where_to_look == "local":
            tags = config.cmds["void"][func]["tags"]["key"]["label dictionary"]
            tags_dict_word = config.cmds["void"][func]["tags"]["key"]["dict_words"]
            return self.dec_function_recognition_keys(
                cmd_str, func, tags, tags_dict_word
            )
        else:
            return self.dec_function_recognition_keys(
                cmd_str,
                func,
                config.cmds["dict_word_cmd_value"],
                config.cmds["dict_words"],
            )


